<?php

// 命名空间
namespace Xzb\Ci3\Helpers\Traits;

/**
 * 排序
 */
trait MoveSort
{
	/**
	 * 自增 位置标识
	 *
	 * @var array
	 */
	protected $incrementPositionCodes = [
		'after',
        'after_to_target'
	];

	/**
	 * 自减 位置标识
	 *
	 * @var array
	 */
	protected $decrementPositionCodes = [
		'before',
        'before_to_target'
	];

    /**
     * 合并 排序自增 位置标识
     *
     * @param string|array
     * @return array
     */
    public function mergeIncrementPosition($code)
    {
        $this->incrementPositionCodes = array_merge(
            $this->incrementPositionCodes,
            is_array($code) ? $code : [$code]
        );

        return $this;
    }

    /**
     * 合并 排序自减 位置标识
     *
     * @param string|array
     * @return array
     */
    public function mergeDecrementPosition($code)
    {
        $this->decrementPositionCodes = array_merge(
            $this->decrementPositionCodes,
            is_array($code) ? $code : [$code]
        );

        return $this;
    }

	/**
	 * 移动排序
	 *
	 * @param mixed $movePk
	 * @param mixed $targetPk
	 * @param string $movePosition
	 * @param string $sortColumn
	 * @param array $filter
	 * @return \Xzb\Ci3\Database\Eloquent\Model
	 */
	public function moveSort($movePk, $targetPk, string $movePosition, string $sortColumn, array $filter = [])
	{
		// 移动 记录
		$moveModel = $this->newModelInstance()::wherePrimaryKey($movePk, $filter)->sole();

		// 目标 记录
		$targetModel = $this->newModelInstance()::wherePrimaryKey($targetPk, $filter)->sole();

		// 是否向前排序
		$whetherSortForward = $moveModel[$sortColumn] > $targetModel[$sortColumn];

		// 新排序
		$newSort = $this->generateNewSort($whetherSortForward, $targetModel[$sortColumn], $movePosition);
		if ($newSort == $moveModel[$sortColumn]) {
			return $moveModel;
		}

		return $this->newModelInstance()::transaction(function ($builder) use ($whetherSortForward, $sortColumn, $newSort, $moveModel, $filter) {
			// 先更新 移动记录 和 目标记录 之间记录的 排序
            if ($whetherSortForward) {
                $result = $this->newModelInstance()::where(array_merge($filter, [
                    $sortColumn . ' >=' => $newSort, // 移动记录 新排序
                    $sortColumn . ' <' => $moveModel[$sortColumn], // 移动记录 旧排序
                ]))->increment($sortColumn);
            }
            else {
                $result = $this->newModelInstance()::where(array_merge($filter, [
                    $sortColumn . ' <=' => $newSort, // 移动记录 新排序
                    $sortColumn . ' >' => $moveModel[$sortColumn], // 移动记录 旧排序
                ]))->decrement($sortColumn);
            }

			// 再更新 移动记录 排序
			$moveModel->update([
                $sortColumn => $newSort,
            ]);

			return $moveModel;
		});
	}

	/**
	 * 生成 新排序
	 *
	 * @param bool $whetherSortForward
	 * @param int $targetSort
	 * @param string $movePosition
	 * @return int
	 */
	protected function generateNewSort($whetherSortForward, $targetSort, $movePosition)
	{
		// 向前排序, 移动记录 在 目标记录 之后
		if ($whetherSortForward && in_array(strtolower($movePosition), $this->incrementPositionCodes)) {
			return $targetSort + 1;
		}

		// 向后排序, 移动记录 在 目标记录 之前
		else if (! $whetherSortForward && in_array(strtolower($movePosition), $this->decrementPositionCodes)) {
			return $targetSort - 1;
		}

		return $targetSort;
	}

}
